const { usequery } = require('./routes/adminroute/shipSRM/server_util.js');
const crypto = require('crypto');
const fetch = require('node-fetch');
const request = require('request');
const { logger } = require('./logger.js');
var Redisdb = require("./db/Redisdb.js");

/**通用请求 fetchsync_util
 * url 地址, type 类型[POST/GET], param 值, rttype  返回类型
 */
async function fetchsync_util(url, type, param, rttype, Authorization) {
    return new Promise(function (resolve, reject) {
        fetch(url, {
            method: type,
            mode: 'cors',
            // credentials: 'include',
            headers: {
                'Content-Type': 'application/json;charset=UTF-8',
                'Authorization': Authorization
            },
            body: JSON.stringify(param)
        }
        ).then(response => {

            return rttype == "json" ? response.json() : response.text();
        }).then(data => {
            resolve(data)

        });

    })
}



class DingTalk {
  constructor() {
    this.appId = 'dingqsncipjyicx7wnoy';
    this.appSecret = 'X7cH4rx5HuNRCUIUm1o6ZS0Qsc3TFamLIvEd2HCBIZnow5wHSedpEBI0jtoJgzzi';
    this.corpId = 'dingdddab0728e5b521f35c2f4657eb6378f';
  }

  // 获取access_token
  async getAccessToken() {
     let res = await fetchsync_util(`https://oapi.dingtalk.com/gettoken?appkey=${this.appId}&appsecret=${this.appSecret}`,
      'GET', {}, 'json')
     logger.info('获取access_token结果:', res);
     return res.access_token
  }

  // 获取钉钉登录二维码
  async getLoginQrCode() {
    try {
      // 使用钉钉扫码登录的重定向地址
      const redirectUri = encodeURIComponent('http://localhost:2233/#/');
      
      // 构建标准的钉钉扫码登录URL
      const url = `https://oapi.dingtalk.com/connect/qrconnect?appid=${this.appId}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${redirectUri}`;
      
      logger.info('生成钉钉登录URL:', url);
      
      return {
        success: true,
        data: url
      };
    } catch (error) {
      logger.error('获取钉钉登录二维码失败:', error);
      return {
        success: false,
        message: '获取钉钉登录二维码失败'
      };
    }
  }

  // 使用授权码获取用户信息
  async checkLoginStatus(code) {
    try {
      if (!code) {
        throw new Error('授权码不能为空');
      }
      
      logger.info('开始处理钉钉登录，授权码:', code);

      // 1. 获取access_token
      const accessToken = await this.getAccessToken();
      logger.info('成功获取access_token:', accessToken);

      // 2. 获取用户信息（使用SNS临时授权码）
      const timestamp = Date.now();
      const signature = this.generateSignature(timestamp);
      
      logger.info('请求参数:', {
        appId: this.appId,
        timestamp,
        signature,
        tmp_auth_code: code
      });

      const userInfoUrl = `https://oapi.dingtalk.com/sns/getuserinfo_bycode?accessKey=${this.appId}&timestamp=${timestamp}&signature=${signature}`;
      const userInfoResponse = await fetch(userInfoUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          tmp_auth_code: code,
        })
      }).then(res => res.json());

      logger.info('获取用户信息结果:', userInfoResponse);

      if (!userInfoResponse.user_info || !userInfoResponse.user_info.unionid) {
        throw new Error(`获取用户信息失败: ${JSON.stringify(userInfoResponse)}`);
      }

      // 3. 根据unionid获取userid
      const userIdUrl = `https://oapi.dingtalk.com/topapi/user/getbyunionid?access_token=${accessToken}`;
      const userIdResponse = await fetch(userIdUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          unionid: userInfoResponse.user_info.unionid
        })
      }).then(res => res.json());

      logger.info('获取userid结果:', userIdResponse);

      if (userIdResponse.errcode !== 0) {
        throw new Error(`获取userid失败: ${JSON.stringify(userIdResponse)}`);
      }

      // 5. 查询数据库，获取用户信息
      const userResult = await usequery(`SELECT * FROM shipSrm_ryda WHERE dd_userid = '${userIdResponse.result.userid}'`);

      if (userResult.length === 0) {
        return {
          success: false,
          message: '用户未绑定，请先完成账号绑定'
        };
      }

      return {
        success: true,
        data: userResult[0]
      };

    } catch (error) {
      logger.error('钉钉登录失败:', error);
      return {
        success: false,
        message: error.message || '登录失败'
      };
    }
  }

  // 生成签名
  generateSignature(timestamp) {
    const crypto = require('crypto');
    
    // 根据timestamp, appSecret计算签名值
    const appSecret = this.appSecret;
    // 使用传入的timestamp作为签名字符串
    const stringToSign = timestamp.toString();
    
    // 使用HMAC-SHA256算法计算签名
    const hmac = crypto.createHmac('sha256', appSecret);
    hmac.update(stringToSign);
    
    // 将结果进行Base64编码
    const signature = hmac.digest('base64');
    
    if (signature === "") {
      return "";
    }
    
    // URL编码处理
    let urlEncodeSignature = encodeURIComponent(signature);
    // 特殊字符替换
    urlEncodeSignature = urlEncodeSignature
      .replace(/\+/g, "%20")
      .replace(/\*/g, "%2A")
      .replace(/~/g, "%7E")
      .replace(/\//g, "%2F");
      
    return urlEncodeSignature;
  }
}

module.exports = DingTalk;